package com.weng.coder.service;

import java.beans.Transient;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.weng.coder.common.utils.Constants;
import com.weng.coder.entity.CoderCondition;
import com.weng.coder.entity.Field;
import com.weng.coder.entity.Project;
import com.weng.framework.core.model.ResponseData;
import com.weng.framework.dao.mybatis.model.page.PageModel;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import com.weng.coder.mapper.CodeTableMapper;
import com.weng.coder.mapper.ColumnMapper;
import com.weng.coder.mapper.FieldMapper;
import com.weng.coder.entity.CodeTable;


/**
 * 表 业务实现类
 *
 * @作者 wengzhonghui
 * @创建时间 2018-02-24 17:25:35
 */
@Service("codeTableService")
public class CodeTableServiceImpl implements CodeTableService {
	
	private static Logger logger = LoggerFactory.getLogger(CodeTableServiceImpl.class);
	@Resource
	private CodeTableMapper codeTableDao;
	@Resource
	private ColumnMapper columnDao;
	@Resource
	private FieldMapper fieldDao;

	@Resource
	private ICoderConditionService coderConditionService;

	@Resource
	private FieldService fieldService;
	@Resource
	private ColumnService columnService;
	@Resource
	private GetTableAndFieldsBySqlService getTableAndFieldsBySqlService;
	
	public List<CodeTable> findByIds(List<String> ids){
		return codeTableDao.selectBatchIds(ids);
			}
	/**
	 * Save
	 * @param t
	 */
	@Transactional
	@Override
	public CodeTable save(CodeTable t) {
			if(StringUtils.isEmpty(t.getId())){
					codeTableDao.insert(t);
			}else{
					codeTableDao.updateById(t);
			}
		return t;
	}

	@Override
	@Transactional
	public void delete(String id) {
		this.fieldService.deleteByTableId(id);
		this.columnService.deleteByTableId(id);
		codeTableDao.deleteById(id);
	}

	@Transient
	public String getWhereSql(CodeTable t) {
		StringBuffer sb = new StringBuffer("where 1=1 ");
		if(!StringUtils.isEmpty(t.getProjectId())){
			sb.append(" and a.projectId= :projectId ");
		}
		if(!StringUtils.isEmpty(t.getCode())){
			sb.append(" and a.code like :code");		
		}
		if(!StringUtils.isEmpty(t.getRemarks())){
			sb.append(" and a.remarks like :remarks");
		}
		return sb.toString();
	}

	@SuppressWarnings("unchecked")
	@Override
	public IPage<CodeTable> getDataByPage(int pageNo, int pageSize, CodeTable t) {

		QueryWrapper<CodeTable> qw = new QueryWrapper<>();
		if(t.getProjectId()!=null){
			qw.eq("PROJECT_ID", t.getProjectId());
		}
		if(t.getCode()!=null){
			qw.like("CODE", "%"+ t.getCode() +"%");
		}
		IPage<CodeTable> page = new PageModel<>(pageNo,pageSize);
		return this.codeTableDao.selectPage(page, qw);
	}

	

	@Override
	@Transactional
	public void delete(CodeTable t) {
		this.fieldService.deleteByTableId(t.getId());
		this.columnService.deleteByTableId(t.getId());
		codeTableDao.deleteById(t.getId());
	}
	

	@Override
	public CodeTable getOne(String id) {
		return codeTableDao.selectById(id);
	}


	@Override
	public void delete(Iterable<CodeTable> entities) {
		if(entities!=null){
			for(CodeTable t:entities){
				this.delete(t);
			}
		}
	}

	@Override
	@Transient
	public void deleteByIds(String[] ids) {
		if(ids!=null && ids.length>0){
			for(String id:ids){
				this.delete(id);
			}
		}
	}
	
	@Override
	@Transactional
	public  int deleteByProjectId(String projectId){
	          this.fieldService.deleteByProjectId(projectId);
	          QueryWrapper<CodeTable> qw = new QueryWrapper<>();
	          qw.eq("PROJECT_ID", projectId);
	   return this.codeTableDao.delete(qw);
    }
    @Resource
    private ProjectService projectService;

	@Override
	@Transactional
	public ResponseData addCodeTableAndFieldsBySql(String projectId, String area, String sql, Model model
					,String entityName, String methodName, String methodType, String remark, HttpServletRequest request){
		StringBuilder tableNames = new StringBuilder();
		StringBuilder existsTableNames = new StringBuilder();
        Project project = projectService.getOne(projectId);
		if(StringUtils.isEmpty(projectId) || project == null){
			return ResponseData.failed("所属的项目ID不能为空!");
		}

		List<CodeTable> tableList = getTableAndFieldsBySqlService.getTableListBySql(project, sql);
		if(tableList!=null && tableList.size()>0){
			try {
				if(StringUtils.isEmpty(area)){
					area = Constants.DEFAULT_AREA;
				}
				QueryWrapper<CodeTable> qw = new QueryWrapper<>();
				qw.eq("PROJECT_ID", projectId);
				List<CodeTable> existsTableList =this.codeTableDao.selectList(qw);
				for(CodeTable table : tableList){
					if(isTableExists(table.getCode(), existsTableList)){
						if(tableNames.length()>0){
							tableNames.append(",");
						}
						existsTableNames.append(table.getCode());
						continue;
					}
					if(StringUtils.isNotEmpty(entityName)){
						table.setEntityName(entityName);
					}
					if(StringUtils.isNotEmpty(methodName)){
						table.setMethodName(methodName);
					}
					if(StringUtils.isNotEmpty(methodType)){
						table.setMethodType(methodType);
					}
					table.setArea(area);
					table.setProjectId(projectId);
					if(StringUtils.isNotEmpty(remark)){
						table.setRemarks(remark);
					}
					CodeTable newtable = this.save(table);
					if(tableNames.length()>0){
						tableNames.append(",");
					}
					tableNames.append(table.getCode());
					List<Field> fieldList = table.getFieldList();
					if(fieldList!=null && fieldList.size()>0){
						for(Field field : fieldList){
							field.setTableId(newtable.getId());
							fieldService.save(field);
						}
					}
					List<CoderCondition> conditionList = table.getConditionList();
					if(conditionList!=null && conditionList.size()>0){
						for(CoderCondition coderCondition : conditionList){
							coderCondition.setTableId(newtable.getId());
							coderConditionService.add(coderCondition);
						}
					}
				}
				
			} catch (Exception e) {
				logger.error(e.getMessage(),e);
				return ResponseData.failed("生成异常，请联系管理员，错误信息为：" + e.getMessage());
			}
			
		}else{
			return ResponseData.failed("请输入规范的SQL脚本！");
		}
		StringBuilder successMsg = new StringBuilder("添加成功");
		if(tableNames.length()>0){
			successMsg.append(" ,成功添加表：" + tableNames.toString());
		}
		if(existsTableNames.length()>0){
			successMsg.append(" ,以下表已经存在不重复添加：" + existsTableNames.toString());
		}
		return ResponseData.success(successMsg.toString());
	}
	
	/**
	 * 判断Table是否已存在
	 * @param tableCode
	 * @param existsTableList
	 * @return
	 */
	private boolean isTableExists(String tableCode, List<CodeTable> existsTableList){
		if(existsTableList!=null && existsTableList.size()>0){
			for(CodeTable oldTable : existsTableList){
				if(tableCode.equalsIgnoreCase(oldTable.getCode())){
					return true;
				}
			}
		}
		return false;
	}
}
